import type { UserInfo } from "/#/store";
import type { RouteRecordRaw } from "vue-router";
import { store } from "/@/store";
import { defineStore } from "pinia";
import { RoleEnum } from "/@/enums/role.enum";
import { GetUserInfoModel, LoginParams } from "/@/api/system/model/user.model";
import { ErrorMessageMode } from "/#/axios";
// import { getLocalCache, setLocalCache } from "/@/utils/cache";
// import { TOKEN_KEY, USER_INFO_KEY, USER_ROLES_KEY } from "/@/enums/cache.enum";
import { router } from "/@/router";
import { PAGE_NOT_FOUND_ROUTE } from "/@/router/routes/error";
import { PageEnum } from "/@/enums/page.enum";
import { usePermissionStore } from "./permission";
import { doLogout, getUserInfo, loginApi } from "/@/api/system/user";
import { isArray } from "/@/utils/internal/isType";
import { useMessage } from "/@/hooks/web/useMessage";
import dayjs from "dayjs";

export interface RecordItem {
  username?: string;
  card?: string;
  dealDate?: string;
  dealTime?: string;
  bank?: string;
  payAccount?: string;
  money?: number;
  icon?: string;
  id?: number;
  payType?: number;
  note?: number;
  card4No?: string;
  createTime?: string;
  bz?: string;
  currentDate?: Array<string>;
  currentTime?: Array<string>;
}

interface UserState {
  userInfo: Nullable<UserInfo>;
  token?: string;
  roleList: RoleEnum[];
  icons?: Array<Record<any, string | number | boolean>>;
  records?: Array<RecordItem>;
  balance?: number;
  expense?: number;
  incomes?: number;
  needZIndex?: boolean;
  currentRecord?: RecordItem;
  sessionTimeout: boolean;
  lastUpdateTime: number;
  uname?: string;
  yestodayIncomes?: number;
  incomesRecords?: Array<RecordItem>;
  threeMonthsRecords?: Array<RecordItem>;
  threeMonthExpence?: number;
  threeMonthIncomes?: number;
}

export const useUserStore = defineStore({
  id: "user",
  state: (): UserState => ({
    // 用户信息
    userInfo: null,
    // token
    token: undefined,
    // 角色列表
    roleList: [],
    // 是否登录过期
    sessionTimeout: false,
    // 最后更新时间
    lastUpdateTime: 0,
    icons: [
      { icon: "cy", title: "餐饮", active: true },
      { icon: "back", title: "退款", active: false },
      { icon: "gw", title: "购物", active: false },
      { icon: "hf", title: "话费", active: false },
      { icon: "jtf", title: "出行", active: false },
      { icon: "wxzz", title: "转账", active: false },
    ],
    records: [],
    balance: 1000000,
    expense: 0,
    incomes: 0,
    needZIndex: false,
    currentRecord: {},
    uname: "小帅",
    yestodayIncomes: 0,
    incomesRecords: [],
    threeMonthsRecords: [],
    threeMonthExpence: 0,
    threeMonthIncomes: 0,
  }),
  getters: {
    // 获取token
    getToken(): string | undefined {
      return this.token;
    },
    // 获取用户信息
    getUserInfo(): Nullable<UserInfo> {
      return this.userInfo;
    },
    // 获取角色列表
    getRoleList(): RoleEnum[] {
      return this.roleList.length > 0 ? this.roleList : [];
    },
    // 获取Session状态
    getSessionTimeout(): boolean {
      return !!this.sessionTimeout;
    },
    // 获取最后更新时间
    getLastUpdateTime(): number {
      return this.lastUpdateTime;
    },
    getIcons(): Array<Record<any, string | number | boolean>> {
      return this.icons || [];
    },
    getRecords(): Array<RecordItem> {
      return (
        this.records!.sort((a: RecordItem, b: RecordItem) => {
          const aDate =
            new Date().getFullYear() +
            "-" +
            a.currentDate![0] +
            "-" +
            a.currentDate![1] +
            " " +
            a.currentTime![0] +
            ":" +
            a.currentTime![1] +
            ":" +
            (Math.round(Math.random() * (60 - 1)) + 1);

          const bDate =
            new Date().getFullYear() +
            "-" +
            b.currentDate![0] +
            "-" +
            b.currentDate![1] +
            " " +
            b.currentTime![0] +
            ":" +
            b.currentTime![1] +
            ":" +
            (Math.round(Math.random() * (60 - 1)) + 1);
          return bDate < aDate ? -1 : 1;
        }) || []
      );
    },
    getBalance(): number {
      return this.balance || 0;
    },
    getExpense(): number {
      return this.expense || 0;
    },
    getIncomes(): number {
      return this.incomes || 0;
    },
    getNeedZIndex(): boolean {
      return this.needZIndex || false;
    },
    getCurrentRecordItem(): RecordItem {
      return this.currentRecord || {};
    },
    getUName(): string {
      return this.uname || "";
    },
    getYestodayIncomes(): number {
      return this.yestodayIncomes || 0;
    },
    getIncomesRecords(): Array<RecordItem> {
      return (
        this.incomesRecords!.sort((a: RecordItem, b: RecordItem) => {
          const aDate =
            new Date().getFullYear() +
            "-" +
            a.currentDate![0] +
            "-" +
            a.currentDate![1] +
            " " +
            a.currentTime![0] +
            ":" +
            a.currentTime![1] +
            ":" +
            (Math.round(Math.random() * (60 - 1)) + 1);

          const bDate =
            new Date().getFullYear() +
            "-" +
            b.currentDate![0] +
            "-" +
            b.currentDate![1] +
            " " +
            b.currentTime![0] +
            ":" +
            b.currentTime![1] +
            ":" +
            (Math.round(Math.random() * (60 - 1)) + 1);
          return bDate < aDate ? -1 : 1;
        }) || []
      );
    },
    getThreeMonthsRecords(): Array<RecordItem> {
      return (
        this.threeMonthsRecords!.sort((a: RecordItem, b: RecordItem) => {
          const aDate =
            new Date().getFullYear() +
            "-" +
            a.currentDate![0] +
            "-" +
            a.currentDate![1] +
            " " +
            a.currentTime![0] +
            ":" +
            a.currentTime![1] +
            ":" +
            (Math.round(Math.random() * (60 - 1)) + 1);

          const bDate =
            new Date().getFullYear() +
            "-" +
            b.currentDate![0] +
            "-" +
            b.currentDate![1] +
            " " +
            b.currentTime![0] +
            ":" +
            b.currentTime![1] +
            ":" +
            (Math.round(Math.random() * (60 - 1)) + 1);
          return bDate < aDate ? -1 : 1;
        }) || []
      );
    },
    getThreeMonthExpence(): number {
      return this.threeMonthExpence || 0;
    },
    getThreeMonthIncomes(): number {
      return this.threeMonthIncomes || 0;
    },
  },
  actions: {
    // 设置token
    setToken(info: string | undefined) {
      this.token = info ? info : ""; // for null or undefined value
    },
    // 设置用户信息
    setUserInfo(info: UserInfo | null) {
      this.userInfo = info;
      this.lastUpdateTime = !info ? 0 : new Date().getTime();
    },
    // 设置角色
    setRoleList(roleList: RoleEnum[]) {
      this.roleList = roleList;
    },
    // 设置登录状态
    setSessionTimeout(flag: boolean) {
      this.sessionTimeout = flag;
    },
    setAllCustomerSettings(uname: string, balance: number, incomes: number) {
      uname && uname !== "" && (this.uname = uname);
      balance && (this.balance = balance);
      incomes && (this.yestodayIncomes = incomes);
    },
    /**
     * @description: 登录
     */
    async login(
      params: LoginParams & {
        goHome?: boolean;
        mode?: ErrorMessageMode;
      },
    ): Promise<GetUserInfoModel | null> {
      try {
        const { goHome = true, mode, ...loginParams } = params;
        const data = await loginApi(loginParams, mode);
        const { token } = data;

        // save token
        this.setToken(token);
        return this.afterLoginAction(goHome);
      } catch (error) {
        return Promise.reject(error);
      }
    },
    /**
     * @description: 登录后
     */
    async afterLoginAction(goHome?: boolean): Promise<GetUserInfoModel | null> {
      if (!this.getToken) return null;
      // 获取用户信息
      const userInfo = await this.getUserInfoAction();

      const permissionStore = usePermissionStore();
      if (!permissionStore.isDynamicAddedRoute) {
        const routes = await permissionStore.buildRoutesAction();
        routes.forEach((route) => {
          router.addRoute(route as unknown as RouteRecordRaw);
        });
        router.addRoute(PAGE_NOT_FOUND_ROUTE as unknown as RouteRecordRaw);
        permissionStore.setDynamicAddedRoute(true);
      }
      goHome && (await router.replace(PageEnum.BASE_HOME));

      return userInfo;
    },
    /**
     * @description: 获取用户信息
     */
    async getUserInfoAction(): Promise<UserInfo | null> {
      if (!this.getToken) return null;
      const userInfo = await getUserInfo();

      const { roles = [] } = userInfo;
      if (isArray(roles)) {
        const roleList = roles.map((item) => item.value) as RoleEnum[];
        this.setRoleList(roleList);
      } else {
        userInfo.roles = [];
        this.setRoleList([]);
      }
      this.setUserInfo(userInfo);
      return userInfo;
    },
    // 登出
    async logout(goLogin = false) {
      if (this.getToken) {
        try {
          await doLogout();
        } catch {
          console.log("注销Token失败");
        }
      }
      this.setToken(undefined);
      this.setUserInfo(null);
      goLogin && router.push(PageEnum.BASE_LOGIN);
    },
    // 登出确认弹窗
    confirmLogout() {
      const { createDialog } = useMessage();
      createDialog({
        title: "温馨提示",
        message: "是否确认退出？",
        showCancelButton: true,
      })
        .then(() => {
          this.logout(true);
        })
        .catch(() => {
          console.log("取消退出");
        });
    },
    changeIconActive(index: number) {
      this.icons!.map((item: any, i: number) => {
        i == index ? (item.active = true) : (item.active = false);
      });
    },
    changIconActiveForName(name: string) {
      this.icons!.map((item: any) => {
        item.icon === name ? (item.active = true) : (item.active = false);
      });
    },
    addRecord(item: RecordItem) {
      this.records!.push(item);
      this.setExpense(item);
      this.setIncomes(item);
    },
    setBalance(payType: number, money: number) {
      if (payType === 1) {
        this.balance = Number(this.balance!) - money;
      } else {
        this.balance = Number(this.balance!) + money;
      }
    },
    setBalanceForEdit(payType: number, money: number) {
      if (payType === 1) {
        this.balance = this.balance! + Number(money)!;
      } else {
        this.balance = this.balance! - Number(money)!;
      }
    },
    setExpense(item: RecordItem) {
      if (item.payType === 1) {
        this.expense = this.expense! + Number(item.money);
      }
    },
    setExpenseForEdit(money: number) {
      if (this.expense! > 0) {
        this.expense = this.expense! - Number(money);
      }
    },
    setIncomesForEdit(money: number) {
      if (this.incomes! > 0) {
        this.incomes = this.incomes! - Number(money);
      }
    },
    setIncomes(item: RecordItem) {
      if (item.payType === 2) {
        this.incomes = this.incomes! + Number(item.money);
      }
    },
    setNeedZIndex(flag: boolean) {
      this.needZIndex = flag;
    },
    deleteItemOfRecord(item: RecordItem) {
      const { id, money, payType } = item;
      if (payType === 1) {
        this.expense! -= Number(money)!;
        this.balance! += Number(money)!;
      } else {
        this.balance! -= Number(money)!;
        this.incomes! -= Number(money)!;
      }
      this.records = this.records!.filter((item: RecordItem) => item.id !== id);
      this.records.map((item: RecordItem) => {
        if (payType === 1) {
          item.note! += Number(money)!;
        } else {
          item.note! -= Number(money)!;
        }
      });
    },
    setCurrentRecordItem(item: RecordItem) {
      this.currentRecord = { ...item };
    },
    updateRecordItem(editItem: RecordItem, index: number) {
      this.records![index] = editItem;
      this.setExpense(editItem);
      this.setIncomes(editItem);
    },
    filterRecords() {
      this.incomesRecords = this.records!.filter((item: RecordItem) => item.payType !== 1);
    },
    filterThreeMonthRecords() {
      const month = dayjs().subtract(3, "month").month() + 1;
      const thisMonth = dayjs().month() + 1;
      console.log(thisMonth);
      console.log(month);
      const array = this.records!.filter((item: RecordItem) => {
        let itemMonth = item.currentDate![0];
        if (itemMonth.toString().indexOf("0") > -1) {
          itemMonth = itemMonth.replace("0", "");
        }

        return Number(itemMonth) > month && Number(itemMonth) <= thisMonth;
      });
      let totalExpence = 0;
      let totalIncomes = 0;
      for (const currentItem of array) {
        console.log(currentItem.money);
        console.log(typeof Number(currentItem.money));
        if (currentItem.payType === 1) {
          totalExpence! += Number(currentItem.money!);
        } else {
          totalIncomes! += Number(currentItem.money!);
        }
      }
      this.threeMonthExpence = totalExpence;
      this.threeMonthIncomes = totalIncomes;
      this.threeMonthsRecords = array;
    },
  },
  // 持久化存储插件配置persist 默认使用的是session
  persist: {
    enabled: true,
    strategies: [
      {
        key: "user",
        // storage可自定义见 https://seb-l.github.io/pinia-plugin-persist/advanced/custom-storage.html
        storage: localStorage,
        paths: [
          "token",
          "userInfo",
          "sessionTimeout",
          "records",
          "balance",
          "expense",
          "incomes",
          "uname",
          "yestodayIncomes",
        ],
      },
    ],
  },
});

export function useUserStoreWithOut() {
  return useUserStore(store);
}
